#include "ibtm_in.h"

void FreeeStructBlock( void *pv )
{
	struct StructBlock	*p = (struct StructBlock *)pv ;
	
	if( p )
	{
		if( p->pmem && p->alloc_flag == 1 )
		{
			free( p->pmem );
			p->pmem = NULL ;
		}
		
		free(p);
	}
	
	return;
}

static struct StructBlock *AllocStructBlock( char *name , long struct_size , char *pmem )
{
	struct StructBlock	*p = NULL ;
	
	if( struct_size <= 0 )
	{
		return NULL;
	}
	
	p = (struct StructBlock *)malloc( sizeof(struct StructBlock) ) ;
	if( p == NULL )
	{
		return NULL;
	}
	memset( p , 0x00 , sizeof(struct StructBlock) );
	
	strncpy( p->name , name , MIN(IBP_MAXLEN_STRUCTBLOCK_NAME,strlen(name)) );
	p->struct_size = struct_size ;
	if( pmem )
	{
		p->pmem = pmem ;
		p->alloc_flag = 0 ;
	}
	else
	{
		p->pmem = malloc( struct_size ) ;
		if( p->pmem == NULL )
		{
			FreeeStructBlock( p );
			return NULL;
		}
		memset( p->pmem , 0x00 , struct_size );
		p->alloc_flag = 1 ;
	}
	
	return p;
}

int IBTMAppendStructBlock( struct TransProcessEnv *tpe , char *name , long struct_size , void **ppmem )
{
	void			*pmem = NULL ;
	struct StructBlock	*p = NULL ;
	
	int			nret ;
	
	if( struct_size <= 0 )
	{
		return IBP_IBTM_ERROR_PARAMETER;
	}
	
	nret = IBTMGetStructBlock( tpe , name , struct_size , & pmem ) ;
	if( nret == 0 )
	{
		return IBP_IBTM_ERROR_STRUCT_EXIST;
	}
	
	p = AllocStructBlock( name , struct_size , (*ppmem) ) ;
	if( p == NULL )
	{
		return IBP_IBTM_ERROR_ALLOC;
	}
	(*ppmem) = p->pmem ;
	
	nret = LinkStructBlockTreeNode( tpe , p ) ;
	if( nret )
	{
		FreeeStructBlock( (void*)p );
		return IBP_IBTM_ERROR_ALLOC;
	}
	
	return 0;
}

int IBTMGetStructBlock( struct TransProcessEnv *tpe , char *name , long struct_size , void **ppmem )
{
	struct StructBlock	sb ;
	struct StructBlock	*p = NULL ;
	
	memset( & sb , 0x00 , sizeof(struct StructBlock) );
	strncpy( sb.name , name , MIN(IBP_MAXLEN_STRUCTBLOCK_NAME,strlen(name)) );
	p = QueryStructBlockTreeNode( tpe , & sb ) ;
	if( p == NULL )
		return IBP_IBTM_ERROR_STRUCT_NOT_EXIST;
	
	if( p->struct_size != struct_size )
	{
		return IBP_IBTM_ERROR_STRUCT_SIZE_NOT_MATCH;
	}
	
	(*ppmem) = p->pmem ;
	return 0;
}

int IBTMAppendGetStructBlock( struct TransProcessEnv *tpe , char *name , long struct_size , void **ppmem )
{
	int			nret = 0 ;
	
	nret = IBTMGetStructBlock( tpe , name , struct_size , ppmem ) ;
	if( nret == IBP_IBTM_ERROR_STRUCT_NOT_EXIST )
	{
		(*ppmem) = NULL ;
		return IBTMAppendStructBlock( tpe , name , struct_size , ppmem ) ;
	}
	else if( nret )
	{
		return nret;
	}
	else
	{
		return 0;
	}
}

